package com.apobates.forum.letterbox.dao;

import com.apobates.forum.letterbox.entity.ForumLetter;
import com.apobates.forum.letterbox.entity.ForumLetterTypeEnum;
import com.apobates.forum.letterbox.entity.Inbox;
import com.apobates.forum.utils.persistence.Page;
import com.apobates.forum.utils.persistence.Pageable;
import com.apobates.forum.utils.persistence.PagingAndSortingRepository;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;

/**
 *
 * @author xiaofanku
 * @since 20200510
 */
public interface InboxDao extends PagingAndSortingRepository<ForumLetter, Long> {
    /**
     * 查看指定会员收到的信件,已删除的不显示
     *
     * @param memberId 收件人/会员ID
     * @param pageable 分页请求参数
     * @return
     */
    Page<ForumLetter> findAllByReceiver(long memberId, Pageable pageable);
    
    /**
     * 查看指定会员收到的信件,已删除的不显示.分组发件人,每个发件只出现最近的一条信件
     *
     * @param memberId 收件人/会员ID
     * @param pageable 分页请求参数
     * @return
     */
    Page<ForumLetter> findAllByReceiverGroupSender(long memberId, Pageable pageable);
    
    /**
     * 查看指定会员收到的信件,已删除的不显示
     *
     * @param memberId 收件人/会员ID
     * @param typed 信件类型
     * @param pageable 分页请求参数
     * @return
     */
    Page<ForumLetter> findAllByReceiverAndType(long memberId, ForumLetterTypeEnum typed, Pageable pageable);
    
    /**
     * 查看指定会员寄来的所有信件
     *
     * @param sender 发件人/会员ID
     * @param memberId 收件箱的主人/会员ID
     * @return
     */
    Stream<ForumLetter> findAll(long sender, long memberId);
    
    /**
     * 
     * @param sender
     * @param memberId
     * @param startDateTime
     * @return 
     */
    Stream<ForumLetter> findAll(long sender, long memberId, LocalDateTime startDateTime);
    
    /**
     * 查看指定会员未读的信件
     *
     * @param memberId 收件人/会员ID
     * @param size 显示的数量
     * @return
     */
    Stream<ForumLetter> findAllForUnReadable(long memberId, int size);
    
    /**
     * 查看指定信件的到达记录
     *
     * @param letterIdSet 信件记录ID列表ForumLetter.id(!= Inbox.id)
     * @return
     */
    Stream<Inbox> findAllByLetter(Collection<Long> letterIdSet);
    
    /**
     * 将发件人发送的信件全部标记为阅读
     *
     * @param memberId 收件人
     * @param sender 发件人
     * @return
     */
    Optional<Boolean> editReadabled(long memberId, long sender);
    
    /**
     * 将指定的未读信件标记为已读
     *
     * @param memberId 收件人
     * @param letterIdList 信件记录ID列表ForumLetter.id(!= Inbox.id)
     * @return
     */
    int editReadabled(long memberId, List<Long> letterIdList);
    
    /**
     * 将收件人的未读信件标记为阅读
     *
     * @param memberId 收件人
     * @return
     */
    int editReadabled(long memberId);
    
    /**
     * 将指定的未读信件标记为删除
     *
     * @param memberId 收件人
     * @param letterIdList 信件记录ID列表ForumLetter.id(!= Inbox.id)
     * @return
     */
    int editDeleted(long memberId, List<Long> letterIdList);
    
    /**
     * 批量保存多条收件箱信件到达记录
     *
     * @param letterEntryRecords 信件到达记录
     * @return
     */
    int batchSave(Set<Inbox> letterEntryRecords);
    
    /**
     * 查看指定会员未读的信件数量
     *
     * @param memberId 收件人/会员ID
     * @return
     */
    long countForUnReadable(long memberId);
    
    /**
     * 统计指定发件人的未读信件数量
     *
     * @param memberId 收件人
     * @param senderIdSet 发件人ID集合
     * @return Key = 发件人ID, Value = 收件人未读信件的数量
     */
    Map<Long, Long> groupForUnReadable(long memberId, Set<Long> senderIdSet);
}